<!DOCTYPE html>
<html>
<head>
  <script src="face-api.js"></script>
  <script src="commons.js"></script>
  <script src="js/randomCrop.js"></script>
  <link rel="stylesheet" href="styles.css">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/css/materialize.css">
  <script type="text/javascript" src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/js/materialize.min.js"></script>
</head>
<body>
  <div id="navbar"></div>
  <div class="center-content page-container">
    <div class="progress" id="loader">
      <div class="indeterminate"></div>
    </div>
    <div id="results" class="side-by-side">
      <div id="result0" style="position: relative" class="margin">
        <img id="inputImg0" src="" style="max-width: 400px;" />
        <canvas class="overlay" id="overlay0" />
      </div>
      <div id="result1" style="position: relative" class="margin">
        <img id="inputImg1" src="" style="max-width: 400px;" />
        <canvas class="overlay" id="overlay1" />
      </div>
      <div id="result2" style="position: relative" class="margin">
        <img id="inputImg2" src="" style="max-width: 400px;" />
        <canvas class="overlay" id="overlay2" />
      </div>
    </div>
    <div class="row">
      <label for="imgByNr">Enter image NR: </label>
      <input id="imgByNr" type="text" class="bold" value="0"/>
    </div>
  </div>

  <script>

    const modelCheckpoints = [
      'tmp/face_landmark_68_tiny_model_lr00001_0.weights',
      'tmp/face_landmark_68_tiny_model_lr00001_13.weights',
      'tmp/face_landmark_68_tiny_model_lr00001_24.weights'
    ]
    let originalImage = null

    function cloneImage(img) {
      var image = document.createElement("img")
      image.src = img.src
      return image
    }

    function getInputValue(input) {
      input = input || $('#imgByNr').get(0)
      return input.value || 0
    }

    function onKeyDown(e) {
      e.target.value = (
        parseInt(e.target.value) + (e.keyCode === 38 ? 1 : (e.keyCode === 40 ? -1 : 0))
      ) || getInputValue(e.target)


      const imgUri = `${window.testIds[e.target.value]}.jpg`

      console.log(imgUri)
      onSelectionChanged(imgUri)
    }

    async function updateResults(_landmarks) {
      const inputImgEl = $('#inputImg0').get(0)
      const { width, height } = inputImgEl

      for (let i = 0; i < window.nets.length; i++) {
        const net = window.nets[i]

        const canvas = $(`#overlay${i}`).get(0)
        canvas.width = width
        canvas.height = height
        console.time('detectLandmarks')
        const landmarks = await net.detectLandmarks(inputImgEl)
        console.timeEnd('detectLandmarks')
        faceapi.drawLandmarks(`overlay${i}`, landmarks.forSize(width, height), { drawLines: true })
      }

    }

    async function onSelectionChanged(imgUri) {
      const img = await faceapi.bufferToImage(await fetchImage(imgUri))

      window.nets.forEach(async (_, i) => {
        $(`#inputImg${i}`).get(0).src = img.src
      })
      originalImage = cloneImage(img)
      updateResults()
    }

    async function applyRandomCrop() {
      const dataId = window.testIds[getInputValue()]
      const pts = await (await fetch(`${dataId}.json`)).json()

      const img = cloneImage(originalImage)

      const { croppedImage, shiftedPts } = randomCrop(img, pts)

      img.src = croppedImage.toDataURL()
      $(`#result${0}`).get(0).removeChild($(`#inputImg${0}`).get(0))
      $(`#result${0}`).get(0).appendChild(img)
      window.nets.slice(1).forEach((_, i) => {
        const im = cloneImage(img)
        im.id = `#inputImg${i + 1}`
        $(`#result${i + 1}`).get(0).removeChild($(`#inputImg${i + 1}`).get(0))
        $(`#result${i + 1}`).get(0).appendChild(im)
      })
      const { width, height } = croppedImage
      img.onload = () => updateResults(
        new faceapi.FaceLandmarks68(
          shiftedPts.map(pt =>
            new faceapi.Point(
              pt.x / width,
              pt.y / height
            )
          ),
          { width, height }
        )
      )
    }

    async function loadNetWeights(uri) {
      return new Float32Array(await (await fetch(uri)).arrayBuffer())
    }

    async function run() {
      $('#imgByNr').keydown(onKeyDown)

      //faceapi.loadFaceLandmarkModel('./')

      //window.trainIds = (await fetch('/face_landmarks_train_ids').then(res => res.json()))
      //window.testIds = (await fetch('/face_landmarks_test_ids').then(res => res.json()))
      window.testIds = (await fetch('/strong_sideways_test').then(res => res.json()))

      window.nets = []
      //window.nets.push(faceapi)
      //const net = new faceapi.FaceLandmark68TinyNet()
      //await net.load('./')
      //window.nets.push(net)
      modelCheckpoints.forEach(async checkpoint => {
        const net = new faceapi.FaceLandmark68TinyNet()
        const weights = await loadNetWeights(checkpoint)
        await net.load(weights)
        window.nets.push(net)
      })

      $('#loader').hide()
    }

    $(document).ready(() => run())

  </script>
</body>
</html>